package com.quicks.beauty.server.service;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.quicks.beauty.core.dao.CustomMapper;
import com.quicks.beauty.core.dao.UserAccountDetailMapper;
import com.quicks.beauty.core.dao.UserAddressMapper;
import com.quicks.beauty.core.dao.UserInviteMapper;
import com.quicks.beauty.core.dao.UserPointAccountMapper;
import com.quicks.beauty.core.dao.WxUserMapper;
import com.quicks.beauty.core.entity.UserAccountDetail;
import com.quicks.beauty.core.entity.UserAddress;
import com.quicks.beauty.core.entity.UserAddressExample;
import com.quicks.beauty.core.entity.UserInvite;
import com.quicks.beauty.core.entity.UserInviteExample;
import com.quicks.beauty.core.entity.UserPointAccount;
import com.quicks.beauty.core.entity.UserPointAccountExample;
import com.quicks.beauty.core.entity.WxUser;
import com.quicks.beauty.core.entity.WxUserExample;
import com.quicks.beauty.core.enums.VerifyEnum;
import com.quicks.beauty.core.utils.UUIDGenerator;
import com.quicks.beauty.core.vo.InviteUserVO;
import com.quicks.beauty.core.vo.UserPointsDetailVO;
import com.quicks.beauty.server.vos.WxUserVO;
import org.apache.catalina.User;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class UserService {

    private Logger logger = LoggerFactory.getLogger(UserService.class);


    @Autowired
    private WxUserMapper userMapper;

    @Autowired
    private UserPointAccountMapper pointAccountMapper;

    @Autowired
    private UserAccountDetailMapper accountDetailMapper;

    @Autowired
    private UserAddressMapper addressMapper;

    @Autowired
    private UserInviteMapper userInviteMapper;

    @Autowired
    private CustomMapper customMapper;


    public WxUser getUserById(String id) {
        WxUser wxUser = userMapper.selectByPrimaryKey(id);
        return wxUser;
    }

    public WxUser selectByOpenId(String openId) {
        List<WxUser> wxUsers = userMapper.selectByOpenId(openId, 0);
        if (wxUsers != null && wxUsers.size() > 0) {
            return wxUsers.get(0);
        }
        return null;
    }

    public int updateWxUser(WxUser wxUser) {
        wxUser.setUpdateTime(new Date());
        int i = userMapper.updateByPrimaryKeySelective(wxUser);
        return i;
    }

    @Transactional
    public WxUser addWxUser(String openId, String nickName, String avatar, String fromUserId) {

        WxUser wxUser = selectByOpenId(openId);
        if (wxUser == null) {
            // todo  先查询来源

            Date now = new Date();
            WxUser newUser = new WxUser();
            newUser.setId(UUIDGenerator.generate()).setCreateTime(now).setDeleted(VerifyEnum.Del_Not.getCode())
                    .setNickName(nickName).setAvatar(avatar).setState(VerifyEnum.State_Using.getCode())
                    .setOpenId(openId).setRemark("new").setUpdateTime(now);
            String accountId = UUIDGenerator.generate();

            if (fromUserId != null && hasInviteUser(fromUserId)) {
                UserPointAccount fromUserAccount = getUserPoint(fromUserId);
                if(fromUserAccount!=null){
                    Integer oldPoints = fromUserAccount.getPoints();
                    Integer endPoints = oldPoints + 10;
                    fromUserAccount.setUpdateTime(now);
                    fromUserAccount.setPoints(endPoints);

                    UserInvite invite = new UserInvite();
                    invite.setId(UUIDGenerator.generate());
                    invite.setCreateTime(now);
                    invite.setFromUser(fromUserId);
                    invite.setOpenId(openId);
                    invite.setToUser(newUser.getId());
                    invite.setPoints(10);
                    userInviteMapper.insert(invite);
                    pointAccountMapper.updateByPrimaryKeySelective(fromUserAccount);
                    invitePointAccountDetail(fromUserId, fromUserAccount.getId(), now);
                }
            }

            userMapper.insert(newUser);
            insertPointAccount(newUser.getId(), accountId, now);
            insertAccountDetail(newUser.getId(), accountId, now, 1);
            return newUser;
        } else {
            logger.info("该 {} 用户已经存在,", openId);
            return wxUser;
        }
    }

    public UserPointAccount insertPointAccount(String userId, String accountId, Date date) {
        UserPointAccount account = new UserPointAccount();
        account.setId(accountId);
        account.setUserId(userId);
        account.setCreateTime(date);
        account.setDeleted(0);
        account.setPoints(0);
        account.setRemark("new");
        account.setState(0);
        account.setUpdateTime(date);
        int insert = pointAccountMapper.insert(account);
        return account;
    }


    public UserAccountDetail insertAccountDetail(String userId, String accountId, Date date, int kinds) {
        UserAccountDetail detail = new UserAccountDetail();
        detail.setId(userId);
        detail.setAccountId(accountId);
        detail.setUserId(userId);
        detail.setCreateTime(date);
        detail.setPoints(0);
        detail.setStates(0);
        detail.setKinds(kinds);
      //  UserPointAccount userPointAccount = pointAccountMapper.selectByPrimaryKey(accountId);
        detail.setSurplusPoints(0);
        int insert = accountDetailMapper.insert(detail);
        return detail;
    }

    public UserAccountDetail invitePointAccountDetail(String userId, String accountId, Date date) {
        UserAccountDetail detail = new UserAccountDetail();
        detail.setId(UUIDGenerator.generate());
        detail.setUserId(userId);
        detail.setAccountId(accountId);
        detail.setCreateTime(date);
        detail.setPoints(10);
        detail.setStates(0);
        detail.setKinds(3);
        UserPointAccount userPointAccount = pointAccountMapper.selectByPrimaryKey(accountId);
        int  ui = userInviteMapper.getCount(userId);
        if(ui<=100){
            detail.setSurplusPoints(userPointAccount.getPoints()+10);
        }else{
            detail.setSurplusPoints(userPointAccount.getPoints()+0);
        }
        int insert = accountDetailMapper.insert(detail);
        return detail;
    }

    public List<UserPointsDetailVO> getUserPointsList(String userId, Integer pageNum, Integer pageSize) {
        PageHelper.startPage(pageNum, pageSize, true);
        Page<UserPointsDetailVO> pager = accountDetailMapper.getUserPointsDetailVO(userId);
        List<UserPointsDetailVO> result = pager.getResult();
        return result;
    }

    public int getUserTotalPoint(String userId) {
        UserPointAccountExample example = new UserPointAccountExample();
        UserPointAccountExample.Criteria criteria = example.createCriteria();
        criteria.andUserIdEqualTo(userId);
        List<UserPointAccount> accounts = pointAccountMapper.selectByExample(userId);
        if (!accounts.isEmpty()) {
            UserPointAccount account = accounts.get(0);
            Integer points = account.getPoints();
            return points.intValue();
        }
        return 0;
    }

    public WxUserVO getMySelfByOpenId(String openId) {
        WxUserVO userVO = new WxUserVO();
        WxUserExample example = new WxUserExample();
        WxUserExample.Criteria criteria = example.createCriteria();
        criteria.andOpenIdEqualTo(openId).andDeletedEqualTo(0).andStateEqualTo(0);


        List<WxUser> userList = userMapper.selectByExample(example);
        if (!userList.isEmpty()) {
            WxUser wxUser = userList.get(0);
            String id = wxUser.getId();
            SimpleDateFormat matter = new SimpleDateFormat("yyyyMMdd HH:mm:ss");
            int point = getUserTotalPoint(id);
            userVO.setUserId(id).setOpenId(openId).setPoints(point)
                    .setNickName(wxUser.getNickName()).setAvatar(wxUser.getAvatar())
                    .setRegTime(matter.format(wxUser.getCreateTime()));
            return userVO;
        }
        return null;
    }

    public UserAddress addUserAddress(String userId, String province, String city, String town, String others, String mobile, String username) {
        UserAddress address = new UserAddress();
        address.setId(UUIDGenerator.generate())
                .setUserId(userId).setProvince(province).setCity(city).setTown(town)
                .setOthers(others).setCreateTime(new Date())
                .setMobile(mobile).setUsername(username).setRemark("").setSorted(0);
        int insert = addressMapper.insert(address);
        return address;
    }

    public List<UserAddress> getUserAddressList(String userId) {
        UserAddressExample example = new UserAddressExample();
        UserAddressExample.Criteria criteria = example.createCriteria();
        criteria.andUserIdEqualTo(userId);
        List<UserAddress> list = addressMapper.selectByExample(example);
        if (!list.isEmpty()) {
//            list.forEach(uad ->{
//                String mobile = uad.getMobile();
//                String start = mobile.substring(0, 3);
//                String end = mobile.substring(7);
//                uad.setMobile(start+"****"+end);
//            });
            List<UserAddress> collect = list.stream().sorted(Comparator.comparing(UserAddress::getCreateTime).reversed()).collect(Collectors.toList());
            return collect;
        }
        return list;
    }

    public boolean hasInviteUser(String fromUserId) {
        UserInviteExample example = new UserInviteExample();
        example.createCriteria().andFromUserEqualTo(fromUserId);
        int count = userInviteMapper.countByExample(example);
        if (count <= 50) {
            return true;
        } else {
            return false;
        }

    }

    public UserPointAccount getUserPoint(String userId) {
       /* UserPointAccountExample example = new UserPointAccountExample();
        example.createCriteria().andUserIdEqualTo(userId).andDeletedEqualTo(0);
        example.setOrderByClause("create_time desc");*/
        List<UserPointAccount> list = pointAccountMapper.selectByExample(userId);
        if (list.isEmpty()) {
            return null;
        } else {
            return list.get(0);
        }
    }

    public List<InviteUserVO> getUserInvited(String userId){
        List<InviteUserVO> invited = customMapper.getUserInvited(userId);
        return invited;
    }

    public int findOrderNum(String invitedUserId) {
        int count  = customMapper.findOrderNum(invitedUserId);
        return count;
    }

    public Map<String,Object> getBillAmount(String invitedUserId) {
        Map<String,Object> map = customMapper.getBillAmount(invitedUserId);
        return map;
    }
}
